import pygame
import random
import time

# 初始化 Pygame
pygame.init()

# 设置游戏窗口大小
width, height = 450, 650
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("雷霆战机")

# 加载背景图片
background_img = pygame.image.load("assets/background.jpg")

# 加载玩家、敌机、子弹和 Boss 图片
player_img = pygame.image.load("assets/player.png")
enemy_img = pygame.image.load("assets/enemy.png")
bullet_img = pygame.image.load("assets/bullet.png")
boss_img = pygame.image.load("assets/boss.png")

# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)


# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, action=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.action = action
        # 使用系统默认字体，设置字号为 36
        self.font = pygame.font.SysFont(None, 36)

    def draw(self, surface):
        pygame.draw.rect(surface, WHITE, self.rect)
        # 渲染文字，抗锯齿开启，颜色为黑色
        text_surface = self.font.render(self.text, True, BLACK)
        text_rect = text_surface.get_rect(center=self.rect.center)
        surface.blit(text_surface, text_rect)

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.rect.collidepoint(event.pos):
                if self.action:
                    self.action()


# 玩家类,pygame.sprite.Sprite是用于创建和管理游戏对象的基类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = player_img
        self.rect = self.image.get_rect()
        self.rect.centerx = width // 2
        self.rect.bottom = height - 10
        self.speedx = 0
        self.speedy = 0
        self.health = 3  # 初始化生命值为 3
        self.kill_count = 0  # 初始化击杀数为 0
        self.invincible = False
        self.invincible_start_time = 0
        self.invincible_duration = 2000  # 无敌时间（毫秒）

    def update(self):
        # 控制玩家移动
        self.speedx = 0
        self.speedy = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -5
        if keystate[pygame.K_RIGHT]:
            self.speedx = 5
        if keystate[pygame.K_UP]:
            self.speedy = -5
        if keystate[pygame.K_DOWN]:
            self.speedy = 5
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.right > width:
            self.rect.right = width
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > height:
            self.rect.bottom = height

        # 处理无敌状态
        if self.invincible:
            current_time = pygame.time.get_ticks()
            if current_time - self.invincible_start_time >= self.invincible_duration:
                self.invincible = False

    def shoot(self):
        # 创建子弹
        bullet = Bullet(self.rect.centerx, self.rect.top)
        all_sprites.add(bullet)
        bullets.add(bullet)


# 敌机类
class Enemy(pygame.sprite.Sprite):
    def __init__(self, level):
        pygame.sprite.Sprite.__init__(self)
        self.image = enemy_img
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(width - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speedy = random.randrange(1, 3)
        self.speedx = random.randint(-2, 2)  # 增加水平速度
        self.can_shoot = False
        self.last_shoot_time = 0  # 记录上次发射子弹的时间
        self.shoot_interval = 5000  # 发射子弹的时间间隔（毫秒）
        if level == 2:
            self.can_shoot = random.choice([True, False])

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.top > height + 10 or self.rect.right < 0 or self.rect.left > width:
            self.rect.x = random.randrange(width - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speedy = random.randrange(1, 3)
            self.speedx = random.randint(-2, 2)  # 重置水平速度

    def shoot(self):
        current_time = pygame.time.get_ticks()
        if self.can_shoot and current_time - self.last_shoot_time >= self.shoot_interval:
            bullet = EnemyBullet(self.rect.centerx, self.rect.bottom)
            all_sprites.add(bullet)
            enemy_bullets.add(bullet)
            self.last_shoot_time = current_time


# 子弹类
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = bullet_img
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y
        self.speedy = -20  # 加快玩家子弹速度

    def update(self):
        self.rect.y += self.speedy
        if self.rect.bottom < 0:
            self.kill()


# 敌机子弹类
class EnemyBullet(pygame.sprite.Sprite):
    def __init__(self, x, y, speedx=0, speedy=5):  # 加快敌机子弹速度
        pygame.sprite.Sprite.__init__(self)
        self.image = bullet_img
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.top = y
        self.speedx = speedx
        self.speedy = speedy

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.top > height or self.rect.right < 0 or self.rect.left > width:
            self.kill()


# Boss 类
class Boss(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = boss_img
        self.rect = self.image.get_rect()
        self.rect.centerx = width // 2
        self.rect.top = 50  # 降低 Boss 的初始高度
        self.speedx = 2
        self.attack_pattern = 1
        self.last_attack_time = 0
        self. attack_interval= random.randint(1000, 2000)
        self.sprinting = False
        self.sprint_start_time = 0
        self.last_bullet_time = 0
        self.bullet_interval = 200  # 子弹发射间隔（毫秒）
        self.vertical_speed = 2  # 垂直移动速度
        self.last_attack_pattern = 0  # 记录上一次的攻击模式
        self.health = 50  # 添加 Boss 血量

    def update(self):
        current_time = pygame.time.get_ticks()
        if not self.sprinting:
            self.rect.x += self.speedx
            if self.rect.right > width or self.rect.left < 0:
                self.speedx = -self.speedx

            if current_time - self.last_attack_time >= self.attack_interval:
                self.attack()
                self.attack_interval = random.randint(1000, 2000)
                self.last_attack_time = current_time
        elif self.rect.y < height - self.rect.height:
            self.rect.y += 5
        else:
            self.sprinting = False
            self.rect.y = 50 # 将 Boss 重置到顶部
            self.last_attack_time = current_time

    def attack(self):
        possible_patterns = [1, 2, 3, 4]  # 添加新的攻击模式
        if self.last_attack_pattern == 4:
            possible_patterns.remove(4)

        self.attack_pattern = random.choice(possible_patterns)
        self.last_attack_pattern = self.attack_pattern

        if self.attack_pattern == 1:
            # 第一次攻击：下方、左下、右下发射连续三排的子弹，每排间隔开
            for i in range(3):
                bullet_down = EnemyBullet(self.rect.centerx, self.rect.bottom + i * 20)
                bullet_left = EnemyBullet(self.rect.centerx, self.rect.bottom + i * 20, -2, 3)
                bullet_right = EnemyBullet(self.rect.centerx, self.rect.bottom + i * 20, 2, 3)
                all_sprites.add(bullet_down)
                all_sprites.add(bullet_left)
                all_sprites.add(bullet_right)
                enemy_bullets.add(bullet_down)
                enemy_bullets.add(bullet_left)
                enemy_bullets.add(bullet_right)
        elif self.attack_pattern == 2:
            for i in range(10):
                bullet_down = EnemyBullet(self.rect.centerx, self.rect.bottom + i * 20)
                all_sprites.add(bullet_down)
                enemy_bullets.add(bullet_down)
        elif self.attack_pattern == 3:
            # 第三次攻击：向下冲刺
            self.sprinting = True
            self.sprint_start_time = pygame.time.get_ticks()
        elif self.attack_pattern == 4:
            # 新的攻击模式：发射扇形子弹
            for angle in range(-30, 31, 10):
                speedx = int(3 * (angle / 30))
                speedy = 3
                bullet = EnemyBullet(self.rect.centerx, self.rect.bottom, speedx, speedy)
                all_sprites.add(bullet)
                enemy_bullets.add(bullet)


# 创建精灵组
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()
enemy_bullets = pygame.sprite.Group()

# 创建玩家
player = Player()

# 游戏状态
START_SCREEN = 0
GAME_RUNNING = 1
GAME_OVER = 2
BOSS_LEVEL = 3
GAME_WIN = 4
game_state = START_SCREEN

# 当前关卡
level = 1

# 关卡提示相关变量
show_level_prompt = False
level_prompt_start_time = 0
prompt_duration = 3000  # 提示显示时间（毫秒）


# 开始游戏函数
def start_game():
    global game_state, level, show_level_prompt, level_prompt_start_time
    game_state = GAME_RUNNING
    all_sprites.empty()
    enemies.empty()
    bullets.empty()
    enemy_bullets.empty()
    all_sprites.add(player)
    if level == 1:
        for i in range(8):
            enemy = Enemy(level)  # 根据当前关卡设置敌人属性
            all_sprites.add(enemy)
            enemies.add(enemy)
    elif level == 2:
        for i in range(6):
            enemy = Enemy(level)  # 根据当前关卡设置敌人属性
            all_sprites.add(enemy)
            enemies.add(enemy)
    show_level_prompt = True
    level_prompt_start_time = pygame.time.get_ticks()


# 进入 Boss 关卡函数
def start_boss_level():
    global game_state, show_level_prompt, level_prompt_start_time
    game_state = BOSS_LEVEL
    all_sprites.empty()
    enemies.empty()
    bullets.empty()
    enemy_bullets.empty()
    all_sprites.add(player)
    boss = Boss()
    all_sprites.add(boss)
    enemies.add(boss)
    show_level_prompt = True
    level_prompt_start_time = pygame.time.get_ticks()


# 退出游戏函数
def quit_game():
    global running
    running = False


# 重新开始游戏函数
def restart_game():
    global level
    level = 1
    player.kill_count = 0
    player.health = 3
    player.rect.centerx = width // 2
    player.rect.bottom = height - 10
    start_game()


# 开始界面按钮
start_button = Button(width // 2 - 100, height // 2 - 50, 200, 50, "start", start_game)
quit_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "exit", quit_game)

# 结束界面按钮
restart_button = Button(width // 2 - 100, height // 2 - 50, 200, 50, "restart", restart_game)
quit_end_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "exit", quit_game)

# 胜利界面按钮
restart_win_button = Button(width // 2 - 100, height // 2 - 50, 200, 50, "restart", restart_game)
quit_win_button = Button(width // 2 - 100, height // 2 + 50, 200, 50, "exit", quit_game)

# 游戏主循环
clock = pygame.time.Clock()
running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if game_state == START_SCREEN:
            start_button.handle_event(event)
            quit_button.handle_event(event)
        elif game_state == GAME_OVER:
            restart_button.handle_event(event)
            quit_end_button.handle_event(event)
        elif game_state == GAME_WIN:
            restart_win_button.handle_event(event)
            quit_win_button.handle_event(event)
        elif game_state in [GAME_RUNNING, BOSS_LEVEL]:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    player.shoot()

    if game_state == START_SCREEN:
        screen.blit(background_img, (0, 0))
        start_button.draw(screen)
        quit_button.draw(screen)
    elif game_state == GAME_RUNNING:
        all_sprites.update()

        # 敌机发射子弹
        for enemy in enemies:
            enemy.shoot()

        # 检测子弹与敌机的碰撞
        hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
        for hit in hits:
            player.kill_count += 1  # 增加击杀数
            if player.kill_count == 15 and level == 1:
                level = 2
                start_game()
            elif player.kill_count == 30 and level == 2:
                level = 3
                start_boss_level()
            else:
                enemy = Enemy(level)
                all_sprites.add(enemy)
                enemies.add(enemy)

        # 检测玩家与敌机的碰撞
        hits = pygame.sprite.spritecollide(player, enemies, False)
        if hits and not player.invincible:
            player.health -= 1  # 减少生命值
            player.invincible = True
            player.invincible_start_time = pygame.time.get_ticks()
            for enemy in hits:
                enemy.kill()  # 从所有精灵组中移除敌机
            if player.health <= 0:
                game_state = GAME_OVER

        # 检测玩家与敌机子弹的碰撞
        hits = pygame.sprite.spritecollide(player, enemy_bullets, True)
        if hits and not player.invincible:
            player.health -= 1
            player.invincible = True
            player.invincible_start_time = pygame.time.get_ticks()
            if player.health <= 0:
                game_state = GAME_OVER

        # 绘制背景图片
        screen.blit(background_img, (0, 0))
        # 绘制击杀数和生命值信息
        font = pygame.font.SysFont(None, 30)
        kill_text = font.render(f"Kills: {player.kill_count}", True, BLACK)
        health_text = font.render(f"Health: {player.health}", True, BLACK)
        screen.blit(kill_text, (10, 10))
        screen.blit(health_text, (10, 30))

        # 绘制关卡提示
        if show_level_prompt:
            current_time = pygame.time.get_ticks()
            if current_time - level_prompt_start_time < prompt_duration:
                font = pygame.font.SysFont(None, 74)
                prompt_text = font.render(f"Level {level}", True, WHITE)
                text_rect = prompt_text.get_rect(center=(width // 2, height // 2))
                screen.blit(prompt_text, text_rect)
            else:
                show_level_prompt = False

        all_sprites.draw(screen)
    elif game_state == BOSS_LEVEL:
        all_sprites.update()

        # 检测子弹与 Boss 的碰撞
        hits = pygame.sprite.groupcollide(enemies, bullets, False, True)
        for hit in hits:
            hit.health -= 1
            if hit.health <= 0:
                game_state = GAME_WIN
                hit.kill()

        # 检测玩家与 Boss 的碰撞
        hits = pygame.sprite.spritecollide(player, enemies, False)
        if hits and not player.invincible:
            player.health -= 1  # 减少生命值
            player.invincible = True
            player.invincible_start_time = pygame.time.get_ticks()
            if player.health <= 0:
                game_state = GAME_OVER

        # 检测玩家与敌机子弹的碰撞
        hits = pygame.sprite.spritecollide(player, enemy_bullets, True)
        if hits and not player.invincible:
            player.health -= 1
            player.invincible = True
            player.invincible_start_time = pygame.time.get_ticks()
            if player.health <= 0:
                game_state = GAME_OVER

        # 绘制背景图片
        screen.blit(background_img, (0, 0))
        # 绘制击杀数和生命值信息
        font = pygame.font.SysFont(None, 30)
        kill_text = font.render(f"Kills: {player.kill_count}", True, BLACK)
        health_text = font.render(f"Health: {player.health}", True, BLACK)
        screen.blit(kill_text, (10, 10))
        screen.blit(health_text, (10, 30))

        # 绘制 Boss 血量信息
        for enemy in enemies:
            if isinstance(enemy, Boss):
                boss_health_text = font.render(f"Boss Health: {enemy.health}", True, BLACK)
                screen.blit(boss_health_text, (10, 60))

        # 绘制关卡提示
        if show_level_prompt:
            current_time = pygame.time.get_ticks()
            if current_time - level_prompt_start_time < prompt_duration:
                font = pygame.font.SysFont(None, 74)
                prompt_text = font.render(f"Boss Level", True, WHITE)
                text_rect = prompt_text.get_rect(center=(width // 2, height // 2))
                screen.blit(prompt_text, text_rect)
            else:
                show_level_prompt = False

        all_sprites.draw(screen)
    elif game_state == GAME_OVER:
        screen.blit(background_img, (0, 0))
        font = pygame.font.SysFont(None, 74)
        text = font.render("Game Over", True, WHITE)
        text_rect = text.get_rect(center=(width // 2, height // 2 - 100))
        screen.blit(text, text_rect)
        restart_button.draw(screen)
        quit_end_button.draw(screen)
    elif game_state == GAME_WIN:
        screen.blit(background_img, (0, 0))
        font = pygame.font.SysFont(None, 74)
        text = font.render("You Win!", True, WHITE)
        text_rect = text.get_rect(center=(width // 2, height // 2 - 100))
        screen.blit(text, text_rect)
        restart_win_button.draw(screen)
        quit_win_button.draw(screen)

    pygame.display.flip()

pygame.quit()
